#include <iostream>
using namespace std;

class Student{
    private:
        string name;
        int *age;
    public:
        Student():name(""), age(new int(0)){
            cout << "无参构造函数" << endl;
        }
        Student(string n, int a):name(n), age(new int(a)){
            cout << "有参构造函数" << endl;
        }
        Student(const Student &other):\
            name(other.name), age(new int(*(other.age))){
            cout << "拷贝构造函数" << endl;
        }
        // 拷贝赋值函数
        // 拷贝赋值函数是没有初始化列表的
        Student &operator=(const Student &other){
            cout << "拷贝赋值函数" << endl;
            if(this != &other){
                name = other.name;
                delete age; // 释放指针原来指向的空间  防止内存泄露
                age = new int(*(other.age));
            }
            return *this; // 返回对象自身的引用 是为了方便级联使用的场景 a = b = c;
        }
        ~Student(){
            cout << "析构函数" << endl;
            delete age;
            age = nullptr;
        }
        void show(){
            cout << name << " " << *age << endl;
        }
};

int main(int argc, const char *argv[]){
    Student s1("小明", 18); // 有参构造
    Student s2 = s1; // 拷贝构造
    Student s3; // 无参构造
    s3 = s1; // 拷贝赋值

    s1.show();
    s2.show();
    s3.show();

    cout << "---------------" << endl;
    Student s4; // 无参构造
    Student s5; // 无参构造
    s5 = s4 = s3; // 级联使用的场景 
    // 从编译器的角度  s5.operator=(s4.operator=(s3));
    s4.show();
    s5.show();

    return 0;
}